
/* version 3.6. (c) Copyright 1993-2004 by the University of Washington.
   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, Andrew Keeffe,
   and Dan Fineman.
   Permission is granted to copy and use this program provided no fee is
   charged for it and provided that this copyright notice is not removed. */

#include <ctype.h>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <string>
#include <cassert>
#include <cstdio>
#include <signal.h>
#include <math.h>
#include <trim_string.h>
using std::istream;
#include "phylip.h"

using std::vector;
using std::string;
void tree::setuptree()
{
	// initialize a tree //
	// used in fitch, kitsch, & neighbor //
	for (unsigned i = 0; i < spp; i++ )
	{
		nodep[i]->tip = true;
		nodep[i]->index = i + 1;
		nodep[i]->v = 0.0;
	}
	for (unsigned i = spp; i < nonodes; i++ )
	{
		nodep[i]->index = i + 1;
		nodep[i]->v = 0.0;
		node * p = nodep[i]->next;
		while ( p != nodep[i] )
		{
			p->index = i + 1;
			p = p->next;
		}
	}
	//likelihood = -1.0;
	start = nodep[0];
	//root = NULL;
}  // setuptree //



void tree::allocd()
{
	// used in fitch & kitsch //
	assert(nodep.size()  == nonodes);
	node *p;

	for (unsigned i = 0; i < spp; i++ )
		nodep[i]->d.assign(nonodes, 0.0);

	for (unsigned i = spp; i < nonodes; i++ )
	{
		p = nodep[i];
		for (unsigned j = 1; j <= 3; j++ )
		{
			p->d.assign(nonodes, 0.0);
			p = p->next;
		}
	}
}



void tree::allocw()
{
	// used in fitch & kitsch //
	assert(nodep.size()  == nonodes);
	node *p;

	for (unsigned i = 0; i < spp; i++ )
		nodep[i]->w.assign(nonodes, 1.0);

	for (unsigned i = spp; i < nonodes; i++ )
	{
		p = nodep[i];
		for (unsigned j = 1; j <= 3; j++ )
		{
			p->w.assign(nonodes, 1.0);
			p = p->next;
		}
	}
}




void tree::alloctree(unsigned cnt_species)
{
	// allocate treenode dynamically //
	// used in fitch, kitsch & neighbor //
	nonodes = cnt_species * 2 - 2;

	spp =cnt_species;
	nodes.assign(nonodes + (nonodes - spp) * 2, node());
	nodep.assign(nonodes, 0);
	for (unsigned i =0; i < spp; ++i)
		nodep[i] = &nodes[i];
	unsigned cnt_assigned = spp;

	for (unsigned i = spp; i < nonodes; i++ )
	{
		node* q = 0;
		node* p;
		for (unsigned j = 0; j < 3; j++ )
		{
			p = &nodes[cnt_assigned++];
			p->next = q;
			q = p;
		}
		p->next->next->next = p;
		nodep[i] = p;
	}

	allocd();
	allocw();
	setuptree();

} // alloctree //


